#include "swoole.h"
#include "Server.h"

static int swWorker_onPipeReceive(swReactor *reactor, swEvent *event);

void swWorker_onStart(swServer *serv){
	printf("worker start!!!\n");
}

int swWorker_onTask(swFactory *factory, swEventData *task){
	swServer *serv = factory->ptr;
	//swWorker *worker = SwooleWG.worker;

	switch(task->info.type){
		case SW_EVENT_CONNECT:
			if(serv->onConnect){
				printf("client on connect\n");
				serv->onConnect(serv,&task->info);
			}
			break;
		case SW_EVENT_PACKAGE_END:
			//do not think of big data
			serv->onReceive(serv,task);
			break;
		case SW_EVENT_CLOSE:
			factory->end(factory,task->info.fd);
			break;
	}
}

void swWorker_signal_init(void){
	swSignal_clear();

    swSignal_add(SIGPIPE, NULL);
    swSignal_add(SIGUSR1, NULL);
    swSignal_add(SIGUSR2, NULL);
    swSignal_add(SIGTERM, swWorker_signal_handler);
}

void swWorker_signal_handler(int signo){
	switch(signo){
		case SIGTERM:
			//do not think of async reload
			SwooleG.main_reactor->running = 0;
			break;
		default:
			break;
	}
}

int swWorker_loop(swFactory *factory, int worker_id){
	swServer *serv = factory->ptr;

	SwooleG.use_signalfd = 1;

	SwooleG.pid = getpid();
	SwooleG.main_reactor = malloc(sizeof(swReactor));
	if(SwooleG.main_reactor == NULL){
		return -1;
	}

	swWorker *worker = swServer_get_worker(serv,worker_id);

	//signal init
	swWorker_signal_init();

	if(swReactor_create(SwooleG.main_reactor,SW_REACTOR_MAXEVENTS) < 0){
		return -1;
	}

	int pipe_worker = worker->pipe_worker;

	swSetNonBlock(pipe_worker);
	SwooleG.main_reactor->ptr = serv;

	SwooleG.main_reactor->add(SwooleG.main_reactor, pipe_worker, SW_FD_PIPE | SW_EVENT_READ);
    SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE, swWorker_onPipeReceive);
    SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_WRITE, swReactor_onWrite);

	swWorker_onStart(serv);
	swSignalfd_setup(SwooleG.main_reactor);

	SwooleG.main_reactor->wait(SwooleG.main_reactor, NULL);

	printf("worker shutdown.\n");

	return 0;
}

static int swWorker_onPipeReceive(swReactor *reactor, swEvent *event){
	swEventData task;
	swServer *serv = reactor->ptr;
	swFactory *factory = &serv->factory;
	int ret;

	if(read(event->fd,&task,sizeof(task)) > 0){
		ret = swWorker_onTask(factory, &task);

		return 0;
	}

	return -1;
}

int swWorker_send2reactor(swEventData *ev_data, size_t sendn, int session_id){
	int ret;
	swServer *serv = SwooleG.serv;

	int _pipe_fd = swWorker_get_send_pipe(serv, session_id, ev_data->info.from_id);

	printf("can i arrive here pipefd===%d\n",_pipe_fd);

	ret = SwooleG.main_reactor->write(SwooleG.main_reactor, _pipe_fd, ev_data, sendn);

	printf("====ret is %d=====\n",ret);

	return ret;
}
